﻿using Application.WP8.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Shapes;
using XConductor.Application.Seedwork.Services;
using XConductor.Domain.WP8.Capturing;
using XConductor.Domain.WP8.Capturing.Settings;
using XConductor.Domain.WP8.Media;
using XConductor.Domain.WP8.Playback;
using XConductor.Domain.WP8.Playback.Settings;

namespace XConductor.WP8.App
{
    public sealed class PoingGenerator
    {
        private IEnumerable<Point> m_points;
        private ThreadLocal<Random> m_random = new ThreadLocal<Random>(() => new Random(Guid.NewGuid().GetHashCode()));
        private int m_globalIndex = 0;

        public PoingGenerator(double maxWidth, double maxHeight)
        {
            m_points = 
                ParallelEnumerable
                .Range(0, (int)maxHeight)
                .Select(idx => new Point((int)(maxWidth * this.m_random.Value.NextDouble()), Interlocked.Increment(ref this.m_globalIndex)))
                .OrderBy(i => i.X);
        }

        public IEnumerable<Point> Points
        {
            get { return this.m_points; }
        }
 
    }

    public sealed partial class AudioCapture : XConductor.WP8.App.Common.LayoutAwarePage
    {
        private Polyline pl = new Polyline();

        private readonly String AUDIO_FILE_NAME = "audio.wav";
        private readonly IAudioService m_audioService;

        private bool m_recording = false;
        private bool m_playing = false;

        public AudioCapture()
        {
            this.InitializeComponent();
            this.m_audioService = new AudioService(
                new CaptureSession(), 
                new CaptureSettingsService(),
                new AudioPlayer(),
                new AudioPlayerSettingsService(this.playbackElement));

            pl.Stroke = new SolidColorBrush(Colors.Red);
            pl.StrokeThickness = 1;

            this.playbackCanvas.Children.Add(pl);
        }
        
        internal async void btnStartPlaying_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            try
            {
                if (this.m_recording)
                {
                    this.m_recording = false;
                    await this.m_audioService.EndRecording();
                }

                this.m_playing = true;
                await this.m_audioService.StartPlaying(AUDIO_FILE_NAME);
            }
            catch
            { }
        }

        internal async void btnStopPlaying_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            try
            {
                if (this.m_playing)
                {
                    this.m_playing = false;
                    await this.m_audioService.StopPlaying();
                }
            }
            catch
            { }
        }

        internal async void btnPausePlaying_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            try
            {
                if (this.m_playing)
                {
                    this.m_playing = false;
                    await this.m_audioService.PausePlaying();
                }
            }
            catch
            { }
        }

        internal async void btnStartStopRecord_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            try
            {
                if (!this.m_recording)
                {
                    this.m_playing = false;
                    await this.m_audioService.StopPlaying();

                    this.m_recording = true;
                    await this.m_audioService.StartRecording(AUDIO_FILE_NAME);
                }
                else
                {
                    this.m_recording = false;
                    await this.m_audioService.EndRecording();
                }
            }
            catch
            { }
        }

        internal async void btnReadFile_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            try
            {
                var outFormat = new AudioFormatDescription
                {
                    BytesPerFrame = 2 * 2,
                    ChannelsPerFrame = 2,
                    SampleRate = 44100,
                };

                var inFormat = new AudioFormatDescription
                {
                    BytesPerFrame = 2 * 2,
                    ChannelsPerFrame = 2,
                    SampleRate = 44100,
                };

                var file = await KnownFolders.VideosLibrary.GetFileAsync(AUDIO_FILE_NAME);
                var straem = await file.OpenStreamForReadAsync();

                var provider = new AudioSourceProvider(straem, inFormat);
                using (var transformer = new AudioFormatTransform(provider, outFormat))
                {
                    var second = inFormat.BytesPerFrame * inFormat.SampleRate;
                    var buffer = new byte[second];
                    var count = second;
                    var offset = 0;
                    while (count != 0)
                    {
                        pl.Points.Add(new Point(buffer[0], offset / second));
                        count = transformer.Read(buffer, offset, second);
                        offset += count;
                    }
                }
            }
            catch
            { }
        }

    }
}
